package utils

import (
	"bytes"
	"fmt"
	"github.com/zeromicro/go-zero/core/logx"
	"os"
	"os/exec"
	"strings"
)

/**
 * @Author: way lee
 * @Date: 2024/10/18 09:42
 * @Desc:
 */

func main() {
	osInfo, err := getOSInfo()
	if err != nil {
		fmt.Printf("Failed to get OS info: %v\n", err)
		return
	}

	switch osInfo["ID"] {
	case "centos":
		if strings.HasPrefix(osInfo["VERSION_ID"], "7") {
			installDependencies("centos7")
		} else if strings.HasPrefix(osInfo["VERSION_ID"], "8") {
			installDependencies("centos8")
		} else {
			fmt.Println("Unsupported CentOS version.")
		}
	case "ubuntu":
		switch osInfo["VERSION_ID"] {
		case "18.04":
			installDependencies("ubuntu18")
		case "20.04":
			installDependencies("ubuntu20")
		case "22.04":
			installDependencies("ubuntu22")
		default:
			fmt.Println("Unsupported Ubuntu version.")
		}
	default:
		fmt.Println("Unsupported OS.")
	}
}

func installDependencies(osType string) {
	// Check and install sshpass if not installed
	if !isCommandInstalled("sshpass", "-V") {
		logx.Errorf("sshpass not installed. Installing...")
		if err := installPackage(osType, "sshpass"); err != nil {
			logx.Errorf("Failed to install sshpass: %v", err)
			return
		}
		logx.Infof("sshpass installed successfully.")
	} else {
		logx.Infof("sshpass is already installed.")
	}

	// Check and install rsync if not installed
	if !isCommandInstalled("rsync", "--version") {
		logx.Errorf("rsync not installed. Installing...")
		if err := installPackage(osType, "rsync"); err != nil {
			logx.Errorf("Failed to install rsync: %v", err)
			return
		}
		logx.Infof("rsync installed successfully.")
	} else {
		logx.Infof("rsync is already installed.")
	}
}

// getOSInfo reads and parses /etc/os-release to get the OS information
func getOSInfo() (map[string]string, error) {
	data, err := os.ReadFile("/etc/os-release")
	if err != nil {
		return nil, err
	}

	osInfo := make(map[string]string)
	lines := strings.Split(string(data), "\n")
	for _, line := range lines {
		if len(line) > 0 {
			parts := strings.SplitN(line, "=", 2)
			if len(parts) == 2 {
				osInfo[strings.Trim(parts[0], "\"")] = strings.Trim(parts[1], "\"")
			}
		}
	}
	return osInfo, nil
}

// isCommandInstalled checks if a command is installed by running a version command
func isCommandInstalled(cmdName, versionArg string) bool {
	cmd := exec.Command(cmdName, versionArg)
	var stderr bytes.Buffer
	cmd.Stderr = &stderr
	if err := cmd.Run(); err != nil {
		return false
	}
	return true
}

// installPackage installs a package from the local file
func installPackage(osType, packageName string) error {
	var cmd *exec.Cmd
	switch osType {
	case "centos7", "centos8":
		cmd = exec.Command("sudo", "rpm", "-ivh", fmt.Sprintf("./dependencies/%s-1.06-2.el%s.x86_64.rpm", packageName, osType[len(osType)-1:]))
	case "ubuntu18":
		var packageFile string
		if packageName == "sshpass" {
			packageFile = "sshpass_1.06-1_amd64.deb"
		} else if packageName == "rsync" {
			packageFile = "rsync_3.1.2-2.1ubuntu1.6_amd64.deb"
		}
		cmd = exec.Command("sudo", "dpkg", "-i", fmt.Sprintf("./dependencies/%s", packageFile))
	case "ubuntu20":
		var packageFile string
		if packageName == "sshpass" {
			packageFile = "sshpass_1.06-1_amd64.deb"
		} else if packageName == "rsync" {
			packageFile = "rsync_3.1.3-8_amd64.deb"
		}
		cmd = exec.Command("sudo", "dpkg", "-i", fmt.Sprintf("./dependencies/%s", packageFile))
	case "ubuntu22":
		var packageFile string
		if packageName == "sshpass" {
			packageFile = "sshpass_1.09-1_amd64.deb"
		} else if packageName == "rsync" {
			packageFile = "rsync_3.2.3-8ubuntu3_amd64.deb"
		}
		cmd = exec.Command("sudo", "dpkg", "-i", fmt.Sprintf("./dependencies/%s", packageFile))
	default:
		return fmt.Errorf("unsupported OS type: %s", osType)
	}

	var stderr bytes.Buffer
	cmd.Stderr = &stderr
	if err := cmd.Run(); err != nil {
		return fmt.Errorf("installation error: %v, details: %s", err, stderr.String())
	}
	return nil
}
